﻿using SPSDeploy.Extensions.Configuration;
using SPSDeploy.Extensions.Modules.Compare;
using System.Xml.Linq;
using System.Xml.XPath;

namespace SPSDeploy.Extensions.Controllers
{
    /// <summary>
    /// Compare operation controller
    /// </summary>
    public class CompareController : BaseController
    {

        // Private members
        private readonly string inputFileName;
        private readonly string outputFileName;

        /// <summary>
        /// Initialization
        /// </summary>
        /// <param name="inputFileName"></param>
        /// <param name="outputFileName"></param>
        public CompareController(string inputFileName, string outputFileName)
        {
            this.inputFileName = inputFileName;
            this.outputFileName = outputFileName;
        }

        /// <summary>
        /// Execute operation
        /// </summary>
        public override void Execute()
        {
            OnProgressMessage("Compare started.");
            XElement compare = MapValues(XElement.Load(inputFileName));
            XElement root = new XElement("root");
            XElement farm = new FarmModule(this).Execute(compare.XPathSelectElement("/farm"), root);
            XElement serviceApplications = new ServiceApplicationModule(this).Execute(compare.XPathSelectElement("/farm/serviceApplications"), farm);
            foreach (XElement element in compare.XPathSelectElements("/farm/serviceApplications/serviceApplication[@type='Search Service Application']"))
                new SearchModule(this).Execute(element, serviceApplications);
            Tools.RollupElement(farm, serviceApplications);
            XElement serviceApplicationProxies = new ServiceApplicationProxyModule(this).Execute(compare.XPathSelectElement("/farm/serviceApplicationProxies"), farm);
            foreach (XElement element in compare.XPathSelectElements("/farm/serviceApplicationProxies/serviceApplicationProxy[@type='Search Service Application Proxy']"))
                new SearchProxyModule(this).Execute(element, serviceApplicationProxies);
            Tools.RollupElement(farm, serviceApplicationProxies);
            Tools.RollupElement(root, farm);
            root.Save(outputFileName);
            OnProgressMessage("Compare completed.");
        }

        /// <summary>
        /// Apply value mappings
        /// </summary>
        /// <param name="compare"></param>
        /// <returns></returns>
        private XElement MapValues(XElement compare)
        {
            XElement element;
            foreach (MappingElement mapping in ApplicationSection.Instance.Mappings)
                if ((element = compare.XPathSelectElement(mapping.Expression)) != null)
                    element.Attribute(mapping.Attribute).SetValue(mapping.Value);
            return compare;
        }

    }
}